//
//  MMModel.m
//  runtimeDemo
//
//  Created by kingboyrang on 2021/10/30.
//  Copyright © 2021 wulanzhou. All rights reserved.
//

#import "MMModel.h"
#import <objc/runtime.h>

@implementation MMModel

//归档
- (void)encodeWithCoder:(NSCoder *)encoder {
    unsigned int count = 0;
    //  利用runtime获取实例变量的列表
    Ivar *ivars = class_copyIvarList([self class], &count);
    for (int i = 0; i < count; i ++) {
        //  取出i位置对应的实例变量
        Ivar ivar = ivars[i];
        //  查看实例变量的名字
        const char *name = ivar_getName(ivar);
        //  C语言字符串转化为NSString
        NSString *nameStr = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];
        //  利用KVC取出属性对应的值
        id value = [self valueForKey:nameStr];
        //  归档
        [encoder encodeObject:value forKey:nameStr];
    }
    
    //  记住C语言中copy出来的要进行释放
    free(ivars);
    
}

//解档
- (id)initWithCoder:(NSCoder *)decoder {
    if (self = [super init]) {
        unsigned int count = 0;
        Ivar *ivars = class_copyIvarList([self class], &count);
        for (int i = 0; i < count; i ++) {
            Ivar ivar = ivars[i];
            const char *name = ivar_getName(ivar);
            
            //
            NSString *key = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];
            id value = [decoder decodeObjectForKey:key];
            //  设置到成员变量身上
            [self setValue:value forKey:key];
        }
        
        free(ivars);
    }
    return self;
}


//方法
- (void)start{
    NSLog(@"方法测试");
}

#pragma mark - 获取所有的属性(包括私有的)
- (void)getAllIvar {
    unsigned int count = 0;
    //Ivar：定义对象的实例变量，包括类型和名字。
    //获取所有的属性(包括私有的)
    Ivar *ivars= class_copyIvarList([self class], &count);
    for (int i = 0; i < count; i++) {
        //取出成员变量
        Ivar ivar = ivars[i];
        
        NSString *name = [NSString stringWithUTF8String:ivar_getName(ivar)];
        NSString *type = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];
        NSLog(@"属性 --> %@ 和 %@",name,type);
        
    }
    
}
#pragma mark - 获取所有的方法(包括私有的)
- (void)getAllMethod {
    unsigned int count = 0;
    //获取所有的方法(包括私有的)
    Method *memberFuncs = class_copyMethodList([self class], &count);
    for (int i = 0; i < count; i++) {
        
        SEL address = method_getName(memberFuncs[i]);
        NSString *methodName = [NSString stringWithCString:sel_getName(address) encoding:NSUTF8StringEncoding];
        
        NSLog(@"方法 : %@",methodName);
    }
    
}

@end
